Skip to content

Add kernelUnitLength support to feDiffuseLighting, feSpecularLighting, and feConvolveMatrix - #1127

Open
edco wants to merge 1 commit into
linebender:mainfrom
edco:kernel-unit-length
Open

Add kernelUnitLength support to feDiffuseLighting, feSpecularLighting, and feConvolveMatrix#1127
edco wants to merge 1 commit into
linebender:mainfrom
edco:kernel-unit-length

Conversation

@edco

@edco edco commented Aug 30, 2026

Copy link
Copy Markdown

Implements kernelUnitLength support to enable scale-independent lighting effects.
Fixes #840 if the SVG is updated to include kernelUnitLength:

<svg id="svg1" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
    <title>lighting-color=hsla (SVG 2)</title>
    <desc>Looks like alpha should be ignored.</desc>

    <radialGradient id="rg1" r="0.5">
        <stop offset="0.5" stop-color="white"/>
        <stop offset="1" stop-color="black" stop-opacity="0"/>
    </radialGradient>
    <filter id="filter1" color-interpolation-filters="sRGB">
        <feSpecularLighting in="SourceAlpha" lighting-color="hsla(120, 100%, 25%, 0.5)"
                            specularConstant="8" specularExponent="10"
                            kernelUnitLength="1">
            <fePointLight x="100" y="100" z="10"/>
        </feSpecularLighting>
    </filter>
    <rect id="rect1" x="20" y="20" width="160" height="160"
          fill="url(#rg1)" filter="url(#filter1)"/>

    <!-- image frame -->
    <rect id="frame" x="1" y="1" width="198" height="198" fill="none" stroke="black"/>
</svg>

(without kernelUnitLength in the SVG the current behaviour is not a bug, and remains unchanged)

  • Parse kernelUnitLength in crates/usvg/src/parser/filter.rs for DiffuseLighting, SpecularLighting, and ConvolveMatrix
  • Add kernel_unit_length field and accessors to usvg AST structs
  • Write kernelUnitLength attribute in crates/usvg/src/writer.rs
  • Implement resolution-independent differential step and bilinear sampling in resvg lighting and convolve_matrix filter primitives
  • Add unit and integration tests for kernelUnitLength parsing and rendering

Authored mostly by Gemini 3.7 Flash in Google Antigravity IDE.

…, and feConvolveMatrix

- Parse kernelUnitLength in crates/usvg/src/parser/filter.rs for DiffuseLighting, SpecularLighting, and ConvolveMatrix
- Add kernel_unit_length field and accessors to usvg AST structs
- Write kernelUnitLength attribute in crates/usvg/src/writer.rs
- Implement resolution-independent differential step and bilinear sampling in resvg lighting and convolve_matrix filter primitives
- Add unit and integration tests for kernelUnitLength parsing and rendering
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SVG effect becomes "dim" on higher resolutions

1 participant